package com.xiaoyu.lanling.widget.picker.area;

import android.annotation.SuppressLint;
import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.DatePicker;
import android.widget.FrameLayout;
import android.widget.NumberPicker;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.xiaoyu.lanling.R;
import com.xiaoyu.lanling.data.AreaData;

import java.util.List;

import in.srain.cube.util.StringUtil;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;

public class PickerAreaView extends FrameLayout implements NumberPicker.OnValueChangeListener {

    private NumberPicker mProvincePicker;
    private NumberPicker mCityPicker;
    private NumberPicker mCountyPicker;

    private PickerAreaModel mPickerModel;
    private String mProvinceValue;
    private String mCityValue;
    private String mCountyValue;

    public PickerAreaView(@NonNull Context context) {
        this(context, null);
    }

    public PickerAreaView(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public PickerAreaView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
        initData();
    }

    public String getProvinceValue() {
        return mProvinceValue;
    }

    public String getCityValue() {
        return mCityValue;
    }

    public String getCountyValue() {
        return mCountyValue;
    }

    public void scrollTo(String province, String city, String county) {
        if (mPickerModel == null || mPickerModel.isInvalid) {
            return;
        }
        try {
            if (TextUtils.isEmpty(province)) {
                return;
            }

            final String[] provinceDisplayValues = mProvincePicker.getDisplayedValues();
            if (provinceDisplayValues == null) {
                return;
            }
            for (int i = 0; i < provinceDisplayValues.length; i++) {
                final String provinceValue = provinceDisplayValues[i];
                if (StringUtil.contains(provinceValue, province)) {
                    mProvincePicker.setValue(i + 1);
                    mProvinceValue = getProvince(i);
                    setCityData(getCityList(i));
                    break;
                }
            }

            final String[] cityDisplayValues = mCityPicker.getDisplayedValues();
            if (cityDisplayValues == null) {
                return;
            }
            for (int i = 0; i < cityDisplayValues.length; i++) {
                final String cityValue = cityDisplayValues[i];
                if (StringUtil.contains(cityValue, city)) {
                    mCityPicker.setValue(i + 1);
                    mCityValue = getCity(mProvincePicker.getValue() - 1, i);
                    setCountyData(getCountyList(mProvincePicker.getValue() - 1, i));
                    break;
                }
            }

            final String[] countyDisplayValues = mCountyPicker.getDisplayedValues();
            if (countyDisplayValues == null) {
                return;
            }
            for (int i = 0; i < countyDisplayValues.length; i++) {
                final String countyValue = countyDisplayValues[i];
                if (StringUtil.contains(countyValue, county)) {
                    mCountyPicker.setValue(i + 1);
                    mCountyValue = getCounty(mProvincePicker.getValue() - 1, mCityPicker.getValue() - 1, i);
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @SuppressLint("InflateParams")
    private void initView() {
        View view = LayoutInflater.from(getContext()).inflate(R.layout.view_picker_area, null);
        mProvincePicker = view.findViewById(R.id.province);
        mCityPicker = view.findViewById(R.id.city);
        mCountyPicker = view.findViewById(R.id.county);

        mProvincePicker.setDescendantFocusability(DatePicker.FOCUS_BLOCK_DESCENDANTS);
        mCityPicker.setDescendantFocusability(DatePicker.FOCUS_BLOCK_DESCENDANTS);
        mCountyPicker.setDescendantFocusability(DatePicker.FOCUS_BLOCK_DESCENDANTS);
        mProvincePicker.setWrapSelectorWheel(false);
        mCityPicker.setWrapSelectorWheel(false);
        mCountyPicker.setWrapSelectorWheel(false);

        mProvincePicker.setOnValueChangedListener(this);
        mCityPicker.setOnValueChangedListener(this);
        mCountyPicker.setOnValueChangedListener(this);

        addView(view);
    }

    @SuppressLint("CheckResult")
    private void initData() {
        AreaData.getInstance().getPickerCityDataModel()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(this::processData, Throwable::printStackTrace);
    }

    private void processData(PickerAreaModel pickerModel) {
        if (pickerModel == null || pickerModel.isInvalid) {
            return;
        }
        mPickerModel = pickerModel;
        setProvinceData(getProvinceList());
        setCityData(getCityList(0));
        setCountyData(getCountyList(0, 0));
    }

    private void setProvinceData(List<String> provinceData) {
        mProvinceValue = provinceData.get(0);

        mProvincePicker.setDisplayedValues(null); // need clean
        mProvincePicker.setMinValue(1);
        mProvincePicker.setMaxValue(provinceData.size());
        mProvincePicker.setDisplayedValues(provinceData.toArray(new String[]{}));
        mProvincePicker.setValue(1);
    }

    private void setCityData(List<String> cityData) {
        mCityValue = cityData.get(0);

        mCityPicker.setDisplayedValues(null); // need clean
        mCityPicker.setMinValue(1);
        mCityPicker.setMaxValue(cityData.size());
        mCityPicker.setDisplayedValues(cityData.toArray(new String[]{}));
        mCityPicker.setValue(1);
    }

    private void setCountyData(List<String> countyData) {
        mCountyValue = countyData.get(0);

        mCountyPicker.setDisplayedValues(null); // need clean
        mCountyPicker.setMinValue(1);
        mCountyPicker.setMaxValue(countyData.size());
        mCountyPicker.setDisplayedValues(countyData.toArray(new String[]{}));
        mCountyPicker.setValue(1);
    }

    @Override
    public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
        if (mPickerModel == null || mPickerModel.isInvalid) {
            return;
        }
        int provinceIndex = 0;
        int cityIndex = 0;
        int countyIndex = 0;

        switch (picker.getId()) {
            case R.id.province:
                provinceIndex = newVal - 1;

                mProvinceValue = getProvince(provinceIndex);
                setCityData(getCityList(provinceIndex));
                setCountyData(getCountyList(provinceIndex, 0));
                break;
            case R.id.city:
                provinceIndex = mProvincePicker.getValue() - 1;
                cityIndex = newVal - 1;

                mCityValue = getCity(provinceIndex, cityIndex);
                setCountyData(getCountyList(provinceIndex, cityIndex));
                break;
            case R.id.county:
                provinceIndex = mProvincePicker.getValue() - 1;
                cityIndex = mCityPicker.getValue() - 1;
                countyIndex = newVal - 1;

                mCountyValue = getCounty(provinceIndex, cityIndex, countyIndex);
                break;
        }
    }

    private String getProvince(int provinceIndex) {
        return mPickerModel.provinceNameList.get(provinceIndex);
    }

    private String getCity(int provinceIndex, int cityIndex) {
        return getCityList(provinceIndex).get(cityIndex);
    }

    private String getCounty(int provinceIndex, int cityIndex, int countyIndex) {
        return getCountyList(provinceIndex, cityIndex).get(countyIndex);
    }

    private List<String> getProvinceList() {
        return mPickerModel.provinceNameList;
    }

    private List<String> getCityList(int provinceIndex) {
        return mPickerModel.cityNameList.get(provinceIndex);
    }

    private List<String> getCountyList(int provinceIndex, int cityIndex) {
        return mPickerModel.countyNameList.get(provinceIndex).get(cityIndex);
    }
}
